/**
 * @file 页面缓存组件 - 优化版
 * @date 2025/11/20 14:32:16
 * @author lyqjob@yeah.net
 * @description 实现LRU缓存策略和路由优先级支持
 */

import { useEffect, useMemo, useRef, useState } from 'react'
import { useLocation, useOutlet } from 'react-router-dom'

const store = new Map()
const order = [] // 按访问时间排序，最近使用的在末尾
let limit = 12

// 路由优先级配置 - 高优先级路由不会被自动删除
const routePriorities = {
  // 添加业务关键页面的路径，赋予高优先级
  // 例如: '/dashboard': 'high',
  //       '/user/profile': 'high',
}

// 根据路径获取优先级，默认medium
const getRoutePriority = (path) => {
  // 支持路径前缀匹配
  for (const [route, priority] of Object.entries(routePriorities)) {
    if (path.startsWith(route)) {
      return priority
    }
  }
  return 'medium'
}


// 移除缓存
const removeKey = (k) => {
    if (!store.has(k)) return
    store.delete(k)
    const idx = order.indexOf(k)
    if (idx >= 0) order.splice(idx, 1)
}

// 将路由移动到最近使用位置（数组末尾）
const moveToRecent = (k) => {
  const idx = order.indexOf(k)
  if (idx >= 0) {
    order.splice(idx, 1)
    order.push(k)
  }
}

// 缓存组件
const KeepAliveOutlet = () => {
    const location = useLocation()
    const outlet = useOutlet()
    const activeKey = location.pathname
    const [, setTick] = useState(0)
    const activeRef = useRef(activeKey)
    activeRef.current = activeKey

    if (outlet) {
        if (!store.has(activeKey)) {
            store.set(activeKey, outlet)
            order.push(activeKey)
            
            // 清理策略：当超过限制时，移除最久未使用且非高优先级的路由
            while (store.size > limit) {
                // 找到第一个可移除的非高优先级路由
                const dropIndex = order.findIndex(key => 
                    getRoutePriority(key) !== 'high' && key !== activeKey
                )
                
                if (dropIndex >= 0) {
                    const dropKey = order[dropIndex]
                    removeKey(dropKey)
                } else {
                    // 如果全是高优先级路由，则移除最久未使用的
                    const dropKey = order.find(key => key !== activeKey)
                    if (dropKey) removeKey(dropKey)
                    break
                }
            }
        } else {
            store.set(activeKey, outlet)
            // 移动到最近使用位置
            moveToRecent(activeKey)
        }
    }

    useEffect(() => {
        const onDrop = (e) => {
            const k = e?.detail?.key
            if (!k) return
            removeKey(k)
            if (k === activeRef.current) setTick((v) => v + 1)
        }
        const onClear = () => {
            store.clear()
            order.splice(0, order.length)
            setTick((v) => v + 1)
        }
        window.addEventListener('keepalive:drop', onDrop)
        window.addEventListener('keepalive:clear', onClear)
        return () => {
            window.removeEventListener('keepalive:drop', onDrop)
            window.removeEventListener('keepalive:clear', onClear)
        }
    }, [])

    const nodes = useMemo(() => {
        const list = []
        for (const [k, el] of store.entries()) {
            list.push(
                <div key={k} style={{ display: k === activeKey ? 'block' : 'none', height: '100%' }}>
                    {el}
                </div>
            )
        }
        return list
    }, [activeKey, store.size])

    return nodes
}

export default KeepAliveOutlet